import java.io.File;
import java.io.IOException;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.regex.Pattern;

import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JLabel;
import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.JButton;
import javax.swing.JScrollPane;
import net.miginfocom.swing.MigLayout;
import javax.swing.SwingConstants;
import javax.swing.ScrollPaneConstants;
import javax.swing.JTextArea;
import javax.swing.DefaultComboBoxModel;
import java.awt.event.ItemListener;
import java.awt.event.ItemEvent;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;


public class AINET_GUI extends JFrame {

	private JPanel contentPane;
	private final JLabel lblSelectDataset = new JLabel("Select a Dataset");
	private final JComboBox cbSelectDataset = new JComboBox(new DefaultComboBoxModel());
	private final JLabel lblNumberOfClasses = new JLabel("Number of Classes:");
	private final JLabel lblValueOfClasses = new JLabel();
	private final JLabel lblNumberOfAttrib = new JLabel("Number of Attributes:");
	private final JLabel lblValueOfAttrib = new JLabel();
	private final JLabel lblSizeOfDataset = new JLabel("Size of Dataset:");
	private final JLabel lblValueOfSize = new JLabel();
	private final JLabel lblTrainingPercent = new JLabel("Antigen Training Percent:");
	private final JFormattedTextField ftfTrainingPercent = new JFormattedTextField(NumberFormat.getPercentInstance());
	private final JLabel lblDeathThreshold = new JLabel("Natural Death Threshold:");
	private JFormattedTextField ftfDeathThreshold;
	private final JLabel lblSuppressThreshold = new JLabel("Suppression Threshold:");
	private JFormattedTextField ftfSuppressThreshold;
	private final JLabel lblAbRatio = new JLabel("Antibody Ratio:");
	private JFormattedTextField ftfAbRatio;
	private final JButton btnRunAinet = new JButton("Run aiNET");
	private final JScrollPane spLog = new JScrollPane();
	private final JLabel lblRatioOne = new JLabel(": 1");
	private final JTextArea txtrLog = new JTextArea();
	
	private ArrayList<String[]> choices = new ArrayList<String[]>();
	private NumberFormat thresholdFormat = NumberFormat.getInstance();
	private NumberFormat ratioFormat = NumberFormat.getInstance();
	private AINET aiNET;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					AINET_GUI frame = new AINET_GUI();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public AINET_GUI() {
		Pattern configPattern = Pattern.compile(",");
		
		// read in contents of dataset configuration file
		try {
			// open the dateset configuration file
			Scanner input = new Scanner(new File("DataSetConfig.txt"));
			
			// read in lines from file until end
			while (input.hasNextLine())
				choices.add(configPattern.split(input.nextLine()));
			
			System.out.println(choices);
			// close the file
			input.close();
		}
		catch (IOException ioe) {
			System.out.println(ioe.getMessage());
		}
		
		// initialize the dataset combo box selections
		for (int i = 0; i < choices.size(); i++) {
			cbSelectDataset.addItem((choices.get(i))[0]);
		}
		
		// initialize GUI elements
		initGUI();
	}
	private void initGUI() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 428, 591);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(new MigLayout("", "[108px][4px][22px][20px:20px][126px][40px:40px][8px]", "[20px][20px][20px][20px][20px][4px][23px][4px][349px,grow]"));
		
		contentPane.add(lblSelectDataset, "cell 0 0 3 1,alignx center");
		contentPane.add(lblTrainingPercent, "cell 4 0,alignx right");
		ftfTrainingPercent.setHorizontalAlignment(SwingConstants.CENTER);
		ftfTrainingPercent.setValue(new Float(0.10));
		contentPane.add(ftfTrainingPercent, "cell 5 0,growx");
		
		cbSelectDataset.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent e) {
				if (e.getStateChange() == ItemEvent.SELECTED) {
					int idx = cbSelectDataset.getSelectedIndex();
					lblValueOfClasses.setText(choices.get(idx)[2]);
					lblValueOfAttrib.setText(choices.get(idx)[3]);
					lblValueOfSize.setText(choices.get(idx)[4]);
				}
			}
		});
		cbSelectDataset.setSelectedIndex(0);
		contentPane.add(cbSelectDataset, "cell 0 1 3 1,growx");
		contentPane.add(lblAbRatio, "cell 4 1,alignx right");	
		ratioFormat.setMaximumIntegerDigits(3);
		ratioFormat.setMinimumIntegerDigits(1);
		ratioFormat.setMaximumFractionDigits(2);
		ftfAbRatio = new JFormattedTextField(ratioFormat);
		ftfAbRatio.setValue(new Double(4));
		ftfAbRatio.setHorizontalAlignment(SwingConstants.CENTER);
		contentPane.add(ftfAbRatio, "cell 5 1,growx");
		contentPane.add(lblRatioOne, "cell 6 1,alignx left");
		
		contentPane.add(lblNumberOfClasses, "cell 0 2,alignx right");
		lblValueOfClasses.setText(choices.get(0)[2]);
		contentPane.add(lblValueOfClasses, "cell 2 2,alignx left");
		contentPane.add(lblDeathThreshold, "cell 4 2,alignx right");
		thresholdFormat.setMaximumFractionDigits(3);
		thresholdFormat.setMinimumFractionDigits(2);
		thresholdFormat.setMaximumIntegerDigits(1);
		thresholdFormat.setMinimumIntegerDigits(1);
		ftfDeathThreshold = new JFormattedTextField(thresholdFormat);
		ftfDeathThreshold.setHorizontalAlignment(SwingConstants.CENTER);
		ftfDeathThreshold.setValue(new Double(0.70));
		contentPane.add(ftfDeathThreshold, "cell 5 2,growx");
		
		contentPane.add(lblNumberOfAttrib, "cell 0 3,alignx right");
		lblValueOfAttrib.setText(choices.get(0)[3]);
		contentPane.add(lblValueOfAttrib, "cell 2 3,alignx left");
		contentPane.add(lblSuppressThreshold, "cell 4 3,alignx right");
		ftfSuppressThreshold = new JFormattedTextField(thresholdFormat);
		ftfSuppressThreshold.setHorizontalAlignment(SwingConstants.CENTER);
		ftfSuppressThreshold.setValue(new Double(0.09));
		contentPane.add(ftfSuppressThreshold, "cell 5 3,growx");
		
		contentPane.add(lblSizeOfDataset, "cell 0 4,alignx right");
		lblValueOfSize.setText(choices.get(0)[4]);
		contentPane.add(lblValueOfSize, "cell 2 4,alignx left");
				
		btnRunAinet.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				// determine index of selected dataset
				int idx = cbSelectDataset.getSelectedIndex();
				
				// create the array of starting indices for each antigen class in data file
				int[] startIdx = new int[choices.get(idx).length - 5];
				for (int i = 0; i < startIdx.length; i++)
					startIdx[i] = Integer.parseInt(choices.get(idx)[5 + i]);
				
				// initialize the data parameters for the aiNET algorithm
				aiNET = new AINET(choices.get(idx)[1], 
								Integer.parseInt(choices.get(idx)[2]), 
								Integer.parseInt(choices.get(idx)[3]),
								Integer.parseInt(choices.get(idx)[4]),
								startIdx,
								(Float)ftfTrainingPercent.getValue(),
								Double.parseDouble(ftfAbRatio.getText()),
								Double.parseDouble(ftfDeathThreshold.getText()),
								Double.parseDouble(ftfSuppressThreshold.getText()));
				
				txtrLog.setText(txtrLog.getText() + "aiNET initialized\n");
				
				// run the aiNET and report results
				txtrLog.setText(txtrLog.getText() + aiNET.runAINET());
			}
		});
		contentPane.add(btnRunAinet, "cell 0 6 7 1,alignx center");
		
		spLog.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
		contentPane.add(spLog, "cell 0 8 7 1,grow");
		txtrLog.setEditable(false);
		txtrLog.setText("");
		spLog.setViewportView(txtrLog);
	}
}
